{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#|default_exp calibration"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Calibration"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">Functionality to calibrate a trained, binary classification model using temperature scaling."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#|export\n",
    "from tsai.imports import *\n",
    "from sklearn.calibration import calibration_curve\n",
    "from tsai.data.core import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#|export\n",
    "class ModelWithTemperature(nn.Module):\n",
    "    \"\"\" A decorator which wraps a model with temperature scaling \"\"\"\n",
    "\n",
    "    def __init__(self, model):\n",
    "        super().__init__()\n",
    "        self.model = model\n",
    "        self.temperature = nn.Parameter(torch.ones(1,1))\n",
    "\n",
    "    def forward(self, input):\n",
    "        logits = self.model(input)\n",
    "        return self.temperature_scale(logits)\n",
    "\n",
    "    def temperature_scale(self, logits):\n",
    "        temperature = self.temperature.expand(logits.size(0), logits.size(1)).to(logits.device)\n",
    "        return torch.div(logits, temperature)\n",
    "\n",
    "\n",
    "class TemperatureSetter(nn.Module):\n",
    "    \"\"\" Calibrates a binary classification model optimizing temperature \"\"\"\n",
    "\n",
    "    def __init__(self, model, lr=0.01, max_iter=1_000, line_search_fn=None, n_bins=10, verbose=True):\n",
    "        super().__init__()\n",
    "        self.model = ModelWithTemperature(model) if not hasattr(model, 'temperature_scale') else model\n",
    "        self.lr, self.max_iter, self.line_search_fn, self.n_bins, self.verbose = lr, max_iter, line_search_fn, n_bins, verbose \n",
    "        self.nll_criterion = CrossEntropyLossFlat()\n",
    "        self.ece_criterion = ECELoss(n_bins)\n",
    "\n",
    "    def forward(self, dl):\n",
    "        logits_list = []\n",
    "        labels_list = []\n",
    "        with torch.no_grad():\n",
    "            for input, label in dl:\n",
    "                logits = self.model(input)\n",
    "                logits_list.append(logits)\n",
    "                labels_list.append(label)\n",
    "            logits = torch.cat(logits_list)\n",
    "            labels = torch.cat(labels_list)\n",
    "\n",
    "        if self.verbose:\n",
    "            before_temperature_nll = self.nll_criterion(logits, labels).item()\n",
    "            before_temperature_ece = self.ece_criterion(logits, labels).item()\n",
    "            print(f'Before temperature - NLL: {before_temperature_nll:.3f}, ECE: {before_temperature_ece:.3f}')\n",
    "\n",
    "        optimizer = torch.optim.LBFGS([self.model.temperature], lr=self.lr, max_iter=self.max_iter, line_search_fn=self.line_search_fn)\n",
    "\n",
    "        def _evaluation():\n",
    "            optimizer.zero_grad()\n",
    "            loss = self.nll_criterion(self.model.temperature_scale(logits), labels)\n",
    "            loss.backward()\n",
    "            return loss\n",
    "\n",
    "        pv('Calibrating the model...', self.verbose)\n",
    "        optimizer.step(_evaluation)\n",
    "        pv('...model calibrated', self.verbose)\n",
    "\n",
    "        if self.verbose:\n",
    "            after_temperature_nll = self.nll_criterion(self.model.temperature_scale(logits), labels).item()\n",
    "            after_temperature_ece = self.ece_criterion(self.model.temperature_scale(logits), labels).item()\n",
    "            print(f'Optimal temperature: {self.model.temperature.item():.3f}')\n",
    "            print(f'After temperature  - NLL: {after_temperature_nll:.3f}, ECE: {after_temperature_ece:.3f}\\n')\n",
    "\n",
    "        self.logits = logits\n",
    "        self.scaled_logits = self.model.temperature_scale(logits)\n",
    "        self.labels = labels\n",
    "        self.calibrated_model = self.model\n",
    "        return self.calibrated_model\n",
    "\n",
    "\n",
    "class ECELoss(nn.Module):\n",
    "    \"\"\"Calculates the Expected Calibration Error of a model.\"\"\"\n",
    "    def __init__(self, n_bins=10):\n",
    "        super().__init__()\n",
    "        bin_boundaries = torch.linspace(0, 1, n_bins + 1)\n",
    "        self.bin_lowers = bin_boundaries[:-1]\n",
    "        self.bin_uppers = bin_boundaries[1:]\n",
    "\n",
    "    def forward(self, logits, labels):\n",
    "        softmaxes = F.softmax(logits, dim=1)\n",
    "        confidences, predictions = torch.max(softmaxes, 1)\n",
    "        if isinstance(softmaxes, TSTensor):\n",
    "            confidences, predictions = confidences.data, predictions.data\n",
    "        accuracies = torch.eq(predictions.data, labels)\n",
    "\n",
    "        ece = torch.zeros(1, device=logits.device)\n",
    "        for bin_lower, bin_upper in zip(self.bin_lowers, self.bin_uppers):\n",
    "            # Calculated |confidence - accuracy| in each bin\n",
    "            in_bin = confidences.gt(bin_lower.item()) * confidences.le(bin_upper.item())\n",
    "            prop_in_bin = in_bin.float().mean()\n",
    "            if prop_in_bin.item() > 0:\n",
    "                accuracy_in_bin = accuracies[in_bin].float().mean()\n",
    "                avg_confidence_in_bin = confidences[in_bin].mean()\n",
    "                ece += torch.abs(avg_confidence_in_bin - accuracy_in_bin) * prop_in_bin\n",
    "        return ece"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#|export\n",
    "def plot_calibration_curve(labels, logits, cal_logits=None, figsize=(6,6), n_bins=10, strategy='uniform'):\n",
    "    y_true = labels.cpu().numpy()\n",
    "    pos_probas = F.softmax(logits, dim=1)[:, 1].detach().cpu().numpy()\n",
    "    nn_y, nn_x = calibration_curve(y_true, pos_probas, n_bins=n_bins, strategy=strategy)\n",
    "    fig, ax = plt.subplots(figsize=figsize)\n",
    "    fig.suptitle(\"Calibration plot\", fontsize=16)\n",
    "    ax.plot(nn_x, nn_y, marker=\"o\", linewidth=1, color='orange', label='probas')\n",
    "    if cal_logits is not None:\n",
    "        pos_cal_probas = F.softmax(cal_logits, dim=1)[:, 1].detach().cpu().numpy()\n",
    "        cal_nn_y, cal_nn_x = calibration_curve(y_true, pos_cal_probas, n_bins=n_bins, strategy=strategy)\n",
    "        ax.plot(cal_nn_x, cal_nn_y, marker=\"o\", linewidth=1, color='purple', label='calibrated probas')\n",
    "    ax.plot([0, 1], [0, 1], transform=ax.transAxes, color='gray', lw=1)\n",
    "    ax.set_xlabel(\"Predicted probability\", fontsize=12)\n",
    "    ax.set_ylabel(\"True probability in each bin\", fontsize=12)\n",
    "    ax.set_xticks(np.linspace(0,1,11))\n",
    "    ax.set_yticks(np.linspace(0,1,11))\n",
    "    ax.set_xlim(0,1)\n",
    "    ax.set_ylim(0,1)\n",
    "    initial_ECE = ECELoss(n_bins)(logits, labels).item()\n",
    "    if cal_logits is not None:\n",
    "        final_ECE = ECELoss(n_bins)(cal_logits, labels).item()\n",
    "        title = f\"initial ECE: {initial_ECE:.3f} - final ECE: {final_ECE:.3f}\"\n",
    "    else:\n",
    "        title = f\"ECE: {initial_ECE:.3f}\"\n",
    "    plt.title(title)\n",
    "    plt.legend(loc='best')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#|export\n",
    "@patch\n",
    "def calibrate_model(self:Learner, X=None, y=None, lr=1e-2, max_iter=10_000, line_search_fn=None, n_bins=10, strategy='uniform', \n",
    "                    show_plot=True, figsize=(6,6), verbose=True):\n",
    "    if X is not None and y is not None: \n",
    "        dl = self.dls.valid.new_dl(X, y)\n",
    "    else: \n",
    "        dl = self.dls.valid\n",
    "    assert dl.c == 2, \"calibrate_model is only available for binary classification tasks\"\n",
    "    temp_setter = TemperatureSetter(self.model, lr=lr, max_iter=max_iter, line_search_fn=line_search_fn, n_bins=n_bins, verbose=verbose)\n",
    "    self.calibrated_model = temp_setter(dl)\n",
    "    if show_plot:\n",
    "        plot_calibration_curve(temp_setter.labels, temp_setter.logits, temp_setter.scaled_logits, n_bins=n_bins, strategy=strategy, figsize=figsize)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tsai.basics import *\n",
    "from tsai.models.FCNPlus import FCNPlus"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0.696826</td>\n",
       "      <td>0.706016</td>\n",
       "      <td>0.430000</td>\n",
       "      <td>00:04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>0.690209</td>\n",
       "      <td>0.699720</td>\n",
       "      <td>0.490000</td>\n",
       "      <td>00:03</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "X, y, splits = get_UCR_data('FingerMovements', split_data=False)\n",
    "tfms  = [None, [TSClassification()]]\n",
    "batch_tfms = TSRobustScale()\n",
    "dls = get_ts_dls(X, y, splits=splits, tfms=tfms, batch_tfms=batch_tfms)\n",
    "learn = ts_learner(dls, FCNPlus, metrics=accuracy)\n",
    "learn.fit_one_cycle(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Before temperature - NLL: 0.700, ECE: 0.066\n",
      "Calibrating the model...\n",
      "...model calibrated\n",
      "Optimal temperature: 6.383\n",
      "After temperature  - NLL: 0.693, ECE: 0.019\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY0AAAGhCAYAAACdyeicAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABZ8ElEQVR4nO3dd5xU1fn48c/DAlJ2YWkiHQSUXmTFggKCBSxU6WU3JuFnjGl+Y8w3JsaY+E2+qd8UE2MSs2yjC4JgR0QiCqggAiJt6b0sZSlbnt8f9y4Ow5a77Mzc2Z3n/XrNi5l7zz33mTvLPHPPufccUVWMMcYYL6r5HYAxxpjKw5KGMcYYzyxpGGOM8cyShjHGGM8saRhjjPHMkoYxxhjPLGmYsBCRW0RktojsE5ELInJURN4UkWQRiStnXU+LiAYtUxF5OriMiFQP0VsoLZ4UEXmohOUqIm3DHcOVKO44etyul7ttw3DEZSoXSxom5ETku8B/gIbAE8CdwEPAF8DfgPtDsJtbgH+GoJ4rkYLzfoItxolrf0SjCb9ewE9xPk8T48L+q8zEFhHpD/we+Iuqfjto9csi8nugbkX3o6ofVLSOIiJylaqer2g9qnoYOByCkIyJWnamYULtCeAY8IPiVqrqNlX9FEBEmojI30XkCxHJFZHdIpIlIi3K2klw81SAziLyjlvffhF5RkSqBWw30N12lIj8Q0QOAwfddR1EJF1EdojIWRHZLiJ/E5EGAdsvAwYA/dx61F1WbPOUiNQQkV+ISLbbTJftvq4RUKatu93/c+PdLyInRGSRiLT0cCyWicgKERkuIp+JyHkR+VxExnrYtp6I/MVtRjwvIptF5HsiIkXvCfi3W3xLwHtuW1KdpmqzMw0TMm5fxR3AAlU952GThsA54L9xfqE3B/4L+I+IdPJYR7AFwIvAL4F7gJ8AhcDTQeX+DLwKTAFqucuaA7uB7wLHgWuBHwFLcJqdAB4BMoA44P+5y06WEs90YCzwP8AK4FbgSbfuiUFl/xt4H6fp62rgd+6+Bpb2hl0dgD/hvM9DwDeAmSJyWFXfKW4DN5kuBm4AngLWA/fhnCk2wXnvi4FfAD8GxgB73M2rWhOc8UpV7WGPkDyApoACv7zC7eOAVm4dIwOWP+38qV5SVoGng8sAPwwq9w/gFJDovh7olpvvIZ7qwG1u+d4By5cBK4opn+KWbeu+7hYcp7v8x+7yHu7rtu7rZUHlvu8ub15GnMvccjcHHcvPgfdKOo44fUsKpATV90/gPNA46H118PtvzB7+P6x5yvhKRL4hIutE5DSQD+xyV11/hVXODno9E4jH+QIPNL+YWGqKyI/cpp2zQB7wXgXi6e/+mxG0vOj1gKDlS4Jer3f/be1hX7s1oJ9HVQuAOUDfwOa5YuIrBLKKia8mX55dGXORJQ0TSkeBs0AbL4VF5FvAX4G3gFFAX+Bmd3WtkrYrw8ESXgf3kxTXvPJLnF/jGTjNNH3duK40nqKrjYL3dSBofZFjQa+LOue97Dv4fRctq4nT1FRSfMdU9YLH+IyxPg0TOqqa73YK3+XxiqTxwNuq+l9FC0SkXQXDaApsD3oNsDc43BLiSVPVXwTEE1+BWIqSwDXAtoDl1wStD4WmJSy7QMlXdB0DGopIzaDEEY74TBVhZxom1H4FNAJ+XdxKEWknIj3cl3VwmoACfaWC+w++Ymg8cJovm3pK4zWe80BtD/UtD4gh0CT332Ue6vCqlYgUnaUVXZQwBlilqoUlbPMuznfAmGLiuwCsdF8XJX8v79lUcXamYUJKVZeLyGPA70WkC5CK00/RABgMfA3nqqFPgdeAJ0TkR8AqYBDwYAVD+Lrbhr8a5+qpr+F0ROd42PY1IFlE1gNbcZqmbi2m3EbgEREZh3MGcUpVNwcXUtXPRGQG8LR7p/r7OP0EPwFmqKqXRObVQWCWiPwU58ziG8B17r8leRXniq7nRaQJsAG4F+eY/VJVj7jlNrr/flNEpuMk1k+LadYyMcCShgk5Vf0/EVkFfA/4LdAY5wqmNTiXqS5yiz4DJLrlauH88r2HS5uXyms4zuW0PwFycC4X/bnHbb8FCPCs+3oJMAEnoQX6X5yO8X/idLK/S8mXxabgvJ+HcK6a2udu/zOPMXm1Fefs7n+AjkA2MEFLuNwWQFULReQ+d5sncM4Qs4HHgP8LKLfOvSdmGvB1nLOTdm5ZE2NE1aZ7NaYyc/uRqqvqbX7HYqo+69MwxhjjmSUNY4wxnlnzlDHGGM/sTMMYY4xnljSMMcZ4ZknDGGOMZ5Y0jDHGeGZJwxhjjGeWNIwxxnhmScMYY4xnljSMMcZ4ZknDGGOMZ5Y0jDHGeGZJwxhjjGeWNCoxEdkgIgNDUVZEXhWRZI91ZYvInV7KGm9E5BsiclBETotII/ffa0NQ79MikhGKGI0BSxqVmqp2VdVl5S1b3BeJqg5V1ekVjUlEUkXkgvulV/RYF7C+prv/LSJyxk1AL4pIW3f9MhE5F7T9ohJ3ePn+J4rITrfuBSLSsJSyvUTkIxHJdf/tFbT+BhFZ7sZwUES+E7T+OyKyw93XJhG5zmucQfXUAH4P3K2q8ap61P23IpNRednvQBEpDDrWp0XkloAy97jH4JSIHBaRd0VkmLsuRUQKitm+ucf9txWRd9zj/3lpP0RE5Cr37+SkiBxwZ4csWldTROa6f0sa/ONIRBJFZLqIHHIfT5fzUJkAljRMOPza/dIrevQMWDcXGIYz5Wt9oCfwEc5UsEUeDdr+AS87FZGuwN+BKUBTIBf4awllawIvAxk4U9FOB152lyMijXGmf/07zox2HYA3Arb/GvBV4D6c2fvuB45wZZrizFy44Qq3r4h9Qcc6XlVXAojIg8AcIA1o6cb5FBD4eawsZvt9Hvc9A/gE5/g+Ccx1p50tztM4MxK2Ae4AfiAiQwLWrwAmAweK2fYPOPO/twX6AlNEpKJz0ccuVbVHJX3gTLd5p/v8aWA2zn/wUzhfQEnBZYEhwAWceZ5PA+vc9cuAr7nP2wNLgaM4X4SZQGJx+y0mplTgFyWsuxM4C7Qq5T1djOMKjsf/AFkBr9u77zWhmLJ3A3txpwdwl+0ChgTUlV7CfqoBu4HBIfgMrwPOAOp+Hkvd5Qp0CDimzwGL3c/2Q6B9QB1/dOM5iZOAbw9Y9zSQUcK+BwJ7Slgn7vF4vJTYU4AVFXjf5wM/G+A94OESyu/DORMrev1zYGYx5fYAA4OWHQFuDHj9I+C9in52sfqwM42qZRgwE2fe7YXAX4ILqOprOF+Is/Tys4AiAvwSaA50BlrhfPlU1J3AKlXdfaUViMgJESlpWtOuwMWmMFXdhpM0ims26gp8qu63iOtTdznAzcAxEXnfbdJYJCKt3XUt3Uc3EdntNlH9TETK/f9JVb8I2Geiqg4qoeh4nHnFG+DMB/5swLrVQC+gIZAFzBGRWuWNJcj1OJ/73CutQET+KiLFnunhvOftqnoqYNk6vjwWgfU0AJoR8NmWVLa0cIKedyvHtiaAJY2qZYWqLlHVAiAdp+mn3FR1q6q+qarnVfUwTnv7gHJU8X33y73oUdRX0gjY72H7PwVt//OA2BJVdUUJ28UDOUHLcoCEKyjbEkgGvgO0BnbgNKcUrQPnbKU7TnPJBJzmqnCZr6qrVDUf58yvV9EKVc1Qpx8kX1V/B1yF86XvRfOgY31CROrifFZQ9ud1c9C22wLiekRVHylhu/J+VkXryypbnNeAH4pIgoh0AB7Caa4yV8CSRtUS2J6bC9QSkerlrUREmorITBHZKyIncdr9G5ejit+6X+5Fj6Krso7i/GIsy7eDtv+Jx/2eBuoFLauH06RT3rJncb6oV6vqOZxf+beKSH13HTh9NydUNRun7+Pe4oIK6iRuXVwZD4I/26IvUkTk+25HfI6InMDpK/L6ee0LOtaJqnoG57OCsj+vD4K2be9xv+X9rIrWl1W2ON/G+cy24PRjzcBpxjJXwJJGbCprjt//cct0V9V6OB2MUvomnrwF9BWRlmWWvDIbCDi7EueS1auAL0oo20NEAt9XD77sjP6US49T4PPNOM1eJa2/hF7aSbzLyxvxSkRuB34AjAUaqGoizq/win5em3H6SUZXsJ6SbACuFZHAs4WeFHMxgKoexznj6VlW2eKo6jFVnaSq16hqV5zvvVVXHHmMs6QRmw4CbUtpg0/A+XWXIyItgMdDsVNVfQt4E5gvIn1EpLrbZPCwiDwUgl1kAg+IyO1uE8szwEtB7eZFlgEFwLfdyzkfdZcvdf/9NzBSnMtyawA/wWn+y1HVXGAWzhU8CW4SnAa8EoL3UF4JQD5wGKguIk9x+S/4cnP7eh4DfiIiXxGReiJSTURuE5EXQlD/F8Ba4KciUktERuIk7XklbJIG/FhEGohIJ+DrOBcIABcvyS3qx6np1inuuvbi3PsSJyJDcT6rX1T0PcQqSxqxaY7771ER+biY9T8DbsD5xboYeKmc9f8gqEkm8FLUB4ElOF+6OcBnQBLOWUiRvwRt/1HRCvf17cXtVFU3AA/jJI9DOF+ojwRs+6qI/MgtewEYAUwFTuC0c49wl6OqS3Guslns1tUB5zLhIo/iJNZ9wEqcDugXPR+h0Hkdp83+C2AncA7nDMGr5nL5fRajAVR1LjAO59jsw/mx8QucJp4itxSz/Y0AIvK8iDxfyr7H43z2x4FfAQ+6fWiIyCQRCTyT+CmwzX2P7wK/cS/qKLIZpwmqhXtMzuJcngvQB1iP05z1S2CS+7diroBcevGIMcYYUzI70zDGGONZRJKGOLf/HxKRz0pYLyLyJxHZKiKfisgNkYjLGGNM+UTqTCMV507kkgzFGSKgI04n1d8iEJMxxphyikjSUNXlwLFSigwH0tTxAZAoIl6u5zfGGBNB0dKn0YJLr/jY4y4zxhgTRcp9t7DfRGQaThMWdevW7dOpUyefIzJR4dhHJa9r2CdycRgTpVSV48ePIyJs3779iKqWNKJwqaIlaezFGRytSEt32WVU9QXgBYCkpCRds2ZN+KMz0W9BW8jdefnyOm1ghP2NmNiWl5fHrFmzqFWrFiNHjqR69erF/GfxJlqapxYCU92rqG4GclTVy8B2xjh6PgtxQWPQxdVxlhsTwy5cuEBWVhZ16tRh1KhRxMXFVai+iJxpiMgMnLH7G4vIHpy7O2sAqOrzOHcI34sz5HMuYBOkmPJpN8n5d92TzhlHrWbQ+zdfLjcmBp0/f56srCwaNmzIAw88QLVqFT9PqNR3hFvzlCnWfyZBs7vg2hS/IzHGN+fOnSMzM5OmTZty3333ETg2p4h8pKpJV1JvtPRphExeXh579uzh3LlzfodiwqhWrVq0bNmSGjVqXL6yQU84/mnkgzImSpw9e5aMjAxatmzJkCFDLkkYFVXlksaePXtISEigbdu2IT1QJnqoKkePHmXPnj20a9fu8gKJPWD/G5cvNyYG5Obmkp6eTrt27bjrrrtC/j0YLR3hIXPu3DkaNWpkCaMKExEaNWpU8tlkYg84sQ4qcdOrMVfi9OnTpKam0qFDh7AkDKiCSQOwhBEDSv2Ma7uDCZw7UHIZY6qYU6dOMX36dLp27cqgQYPC9j1YJZNGZRcfH192IVMyEeds4/g6vyMxJiJycnJITU2lZ8+eDBgwIKw/nC1p7Mh0bgzLqub8uyMzIrstKCiIyH5iVmJPOGGd4abqO3HiBKmpqSQlJXHbbbeFfX+xnTR2ZMKqae6dxOr8u2pahRNHdnY2nTp1YtKkSXTu3JkHH3yQ3Nxc2rZtyxNPPMENN9zAnDlzmDFjBt27d6dbt2488cQTl9Txve99j65duzJ48GAOHz4MwD/+8Q9uvPFGevbsyejRo8nNzQVgzpw5dOvWjZ49e9K/f/8KxV5lNOhhScNUeceOHSM1NZVbbrmFW265JSL7jO2kse5JKMi9dFlBrrO8gjZv3swjjzzCpk2bqFevHn/9618BaNSoER9//DH9+/fniSeeYOnSpaxdu5bVq1ezYMECAM6cOUNSUhIbNmxgwIAB/OxnPwNg1KhRrF69mnXr1tG5c2f+9a9/AfDMM8/w+uuvs27dOhYuXFjh2KsEa54yVdyRI0eYPn06t99+O3379o3YfqvcJbeXybqCtr3cnaVvN7Hsq3JatWpFv379AJg8eTJ/+tOfABg3bhwAq1evZuDAgTRp4owZNmnSJJYvX86IESOoVq3axXKTJ09m1KhRAHz22Wf8+Mc/5sSJE5w+fZp77rkHgH79+pGSksLYsWMvlo159bvA6a1QcB7irvI7GmNC6tChQ2RkZDBo0CB69eoV0X1X/aRR2hd8qYPcZVdot8EdUUWv69ate8V1paSksGDBAnr27ElqairLli0D4Pnnn+fDDz9k8eLF9OnTh48++ohGjRpVKP5KL64WxF8LJzdBg15+R2NMyBw4cIDMzEzuvvtuunfvHvH9x3bzVBgHudu1axcrV64EICsr67IOqr59+/Luu+9y5MgRCgoKmDFjBgMGDACgsLCQuXPnXrbtqVOnaNasGXl5eWRmftnvsm3bNm666SaeeeYZmjRpwu7duzE4neF2Z7ipQvbt20dGRgZDhw71JWFArCeNdpOg7wvOmQXi/Nv3hZAMcnf99dfz3HPP0blzZ44fP843vvGNS9Y3a9aMX/3qV9xxxx307NmTPn36MHz4cMA5G1m1ahXdunVj6dKlPPXUUwD8/Oc/56abbqJfv34EziPy+OOPX+xQv/XWW+nZs2eF468SEq0z3FQde/bsISsri/vvv58uXbr4FkeVG7Bw06ZNdO7c2aeIHNnZ2dx///189tlnvsZR1ZX5We9dApv/AIPejFxQxoTBrl27mDVrFiNGjKBjx44Vrs8GLDSmOA3sXg1T+WVnZzNnzhxGjRpF+/bt/Q4nxpunwqRt27Z2lhENajeHwnw4a8OJmMpp27ZtzJkzhzFjxkRFwgBLGqYqE7GzDVNpbdmyhZdeeolx48bRtm1bv8O5yJKGqdqsM9xUQp9//jkvv/wyEyZMoHXr1n6HcwlLGqZqszvDTSWzYcMGXnnlFSZOnEjLli39DucyljRM1WbNU6YSWb9+Pa+99hqTJ0+mefPmfodTLEsaPktNTeXRRx8FnDu709LSABg4cCAVmf88OzubrKyscm+XkpJy8cbCUApXvWWq1wVOfQEFFyK/b2PKYe3atbz55ptMmTKFa665xu9wShTzl9yuz1zP20++Tc6uHOq3rs/gZwfTfZI/d1o+/PDD5Sqfn59P9erFf4RFSWPixImhCK3C8fimem2o2w5Ofu6MfGtMFProo49Yvnw5U6dOpXHjxn6HU6qYPtNYn7meRdMWkbMzBxRyduawaNoi1meur1C9aWlp9OjRg549ezJlyhQAFi1axE033UTv3r258847OXjw4GXbPf300/z2t7+9+Do9PZ1evXrRrVs3Vq1adbHMlClT6NevH1OmTCE7O5vbb7+dG264gRtuuIH3338fgB/+8Ie899579OrViz/84Q8UFBTw+OOPc+ONN9KjRw/+/ve/A858248++ijXX389d955J4cOHSr2PQ0cOJDvfOc7nuIZNGgQPXr0YPDgwezatetiHW+99RZJSUlcd911vPLKKwAlxr9//3769+9/cX/vvffelX8g1hluotiqVat47733SE5OjvqEATF+pvH2k2+Tl5t3ybK83DzefvLtKz7b2LBhA7/4xS94//33ady4MceOHQPgtttu44MPPkBE+Oc//8mvf/1rfve735VaV25uLmvXrmX58uU89NBDF+/92LhxIytWrKB27drk5uby5ptvUqtWLbZs2cKECRNYs2YNv/rVr/jtb3978cv5hRdeoH79+qxevZrz58/Tr18/7r77bj755BM2b97Mxo0bOXjwIF26dOGhhx664ngeeOABkpOTSU5O5sUXX+Tb3/72xSHfs7OzWbVqFdu2beOOO+5g69atXH311cXGn5WVxT333MOTTz5JQUHBxblDrkgDd85wJl95HcaEwcqVK1m1ahUpKSkkJib6HY4nVT5p/Ex+Vu5tcnbmlLrdT/WnJa5bunQpY8aMufiLoWHDhoAzbsy4cePYv38/Fy5coF27dmXGMWHCBAD69+/PyZMnOXHiBADDhg2jdu3aAOTl5fHoo4+ydu1a4uLi+OKLL4qt64033uDTTz+92K+Qk5PDli1bWL58ORMmTCAuLo7mzZszaNCgCsWzcuVKXnrpJQCmTJnCD37wg4vbjx07lmrVqtGxY0euvfZaPv/8c9q1a1ds/DfeeCMPPfQQeXl5jBgxomLDPyf2hM1/uvLtjQmD9957j7Vr15KSkkL9+vX9DseziCUNERkC/BGIA/6pqr8KWt8GeBFoAhwDJqvqnorut7Qv+P9r+39O01SQ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",
      "text/plain": [
       "<Figure size 432x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.calibrate_model()\n",
    "calibrated_model = learn.calibrated_model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": "IPython.notebook.save_checkpoint();",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/Users/nacho/notebooks/tsai/nbs/052c_calibration.ipynb saved at 2022-11-09 12:54:31\n",
      "Correct notebook to script conversion! 😃\n",
      "Wednesday 09/11/22 12:54:34 CET\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "                <audio  controls=\"controls\" autoplay=\"autoplay\">\n",
       "                    <source src=\"data:audio/wav;base64,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\" type=\"audio/wav\" />\n",
       "                    Your browser does not support the audio element.\n",
       "                </audio>\n",
       "              "
      ],
      "text/plain": [
       "<IPython.lib.display.Audio object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#|eval: false\n",
    "#|hide\n",
    "from tsai.export import get_nb_name; nb_name = get_nb_name(locals())\n",
    "from tsai.imports import create_scripts; create_scripts(nb_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "python3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
